/*  
  -- The Lime II Project -- 

  A tuplespaces-based middleware for coordinating agents and mobile hosts.
  Copyright (C) 2005.
  Gian Pietro Picco, Amy L. Murphy, Lorenzo Bellini.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  Lesser General Public License for more details.

  You should have received this copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
*/

package testing;
import lights.adapters.*;
import lights.interfaces.*;
import java.io.IOException;

/**
 * This class tests the side-effects of modifying tuples read from a LighTS "adapted" tuplespace. Will the original 
 * tuples in the tuplespace be affected, too ? Please note that in order to look at the contents of the tuplespace we 
 * use the "empty tuple" template (= match-all-tuples template according to LighTS specifications).
 * <br>
 * Optional user input: tuplespace adapter to test.
 * 
 * @author Gian Pietro Picco
 * @author Amy Murphy
 * @author Lorenzo Bellini
 */

public class LighTSCopy 
{
 /**
  * Main method.
  * 
  * @param args user input: (optional) name of the tuplespace adapter to test
  */	
 public static void main(String[] args)
 {
  String tsfactory;	
 	
  // if the user did not choose any tuplespace factory then we test the default tuplespace factory
  if (args != null && args.length != 1) tsfactory = "lights.adapters.builtin.TupleSpaceFactory";  
                                   else tsfactory = "lights.adapters." + args[0] + ".TupleSpaceFactory";
 	  
  // sets the tuplespace factory
  try 
  { 
   TupleSpaceFactory.setFactory(tsfactory); 
   System.out.println("tuplespace factory set to " + tsfactory + "\n");
  } 
  catch(ClassNotFoundException cnfe) 
  { 
   System.out.println("can't set tuplespace factory to " + tsfactory); 
   cnfe.printStackTrace();
   System.exit(-1); 
  }	
 	
  try
  {
   // initializes parameters	
   ITupleSpace ts = new TupleSpace("testing");
   ITuple template1 = new Tuple().add(new Field().setType(Integer.class)).add(new Field().setType(Integer.class));
   ITuple template2 = new Tuple().add(new Field().setType(String.class));
   IField change1 = new Field().setValue(new Integer(73));
   ITuple change2 = new Tuple().add(new Field().setValue("changed"));

   // "out" of tuples
   ts.out(new Tuple().add(new Field().setValue(new Integer(100))).add(new Field().setValue(new Integer(200))));
   ts.out(new Tuple().add(new Field().setValue("hello")));
   
   // reads tuples
   System.out.println("tuplespace contains: " + toStringTuples(ts.rdg(new Tuple())));   
   ITuple t1 = ts.rdp(template1);
   System.out.println("t1 <- tuplespace.rdp(<Integer.class, Integer.class>)");
   ITuple t2 = ts.rdp(template2);
   System.out.println("t2 <- tuplespace.rdp(<String.class>)");
   System.out.println("t1 is " + t1);
   System.out.println("t2 is " + t2);
   System.out.println();
   
   // waits key
   System.out.print("press ENTER to modify t1 and t2..");
   waitKey();
   System.out.println();
   
   // modifies the read tuples 
   ((IValuedField) t1.get(0)).setValue(change1); //.. since Field implements IValuedField
   System.out.println("t1.get(0).setValue(" + change1 + ")");
   t2 = change2;
   System.out.println("t2 = " + change2);
   System.out.println("t1 is " + t1);
   System.out.println("t2 is " + t2);
   System.out.println();
   
   // waits key  
   System.out.print("press ENTER to probe tuplespace again..");
   waitKey(); 
   System.out.println();
   
   // shows whether the tuples in the tuplespace have been modified too (side-effect !) 
   System.out.println("tuplespace contains: " + toStringTuples(ts.rdg(new Tuple())));
   System.out.println();
   
   // waits key  
   System.out.print("press ENTER to terminate..");
   waitKey();
  }
  catch (TupleSpaceException tsee) 
  { 
   System.out.println("tuplespace engine error"); 
   tsee.printStackTrace();
   System.exit(-1); 
  } 
 }
 
 // private method: provides textual representation for an array of ITuples
 private static String toStringTuples(ITuple[] tuples)
 {
  String ret = new String("");	
  if (tuples == null) ret = "nothing";
  else {
 	    for (int i = 0; i < tuples.length - 1; i++) ret = ret + tuples[i].toString() + ", ";
 	    ret = ret + tuples[tuples.length - 1];
       }
  return ret;
 } 
 
 // private method for waiting a key (ENTER)
 private static void waitKey()
 {
  try { 
  	   System.in.read();   
  	   System.in.skip(System.in.available());
      }
  catch (IOException ioe) 
  { 
   System.out.println("IOException while waiting key"); 
   ioe.printStackTrace();
   System.exit(-1); 
  }
 }
  
}
 
